using UnityEngine;

public class GameTile : MonoBehaviour {
	
    [SerializeField]
    Transform arrow = default;
    
    GameTile north, east, south, west, nextOnPath;
    
    int distance;
    
    GameTileContent content;

    public Direction PathDirection { get; private set; }
    
    static Quaternion
	    northRotation = Quaternion.Euler(90f, 0f, 0f),
	    eastRotation = Quaternion.Euler(90f, 90f, 0f),
	    southRotation = Quaternion.Euler(90f, 180f, 0f),
	    westRotation = Quaternion.Euler(90f, 270f, 0f);
    
    public bool IsAlternative { get; set; }
    
    public Vector3 ExitPoint { get; private set; }
    
    public GameTile NextTileOnPath => nextOnPath;
    
    public static void MakeEastWestNeighbors (GameTile east, GameTile west) {
	    Debug.Assert(
		    west.east == null && east.west == null, "重新定义的邻居!"
	    );
	    west.east = east;
	    east.west = west;
    }
    
    public static void MakeNorthSouthNeighbors (GameTile north, GameTile south) {
	    Debug.Assert(
		    south.north == null && north.south == null, "重新定义的邻居!"
	    );
	    south.north = north;
	    north.south = south;
    }
    
    public void ClearPath () {
	    distance = int.MaxValue;
	    nextOnPath = null;
    }
    
    public void BecomeDestination () {
	    distance = 0;
	    nextOnPath = null;
	    ExitPoint = transform.localPosition;
    }
    
    public bool HasPath => distance != int.MaxValue;
    
    GameTile GrowPathTo (GameTile neighbor, Direction direction) {
	    Debug.Assert(HasPath, "无路径!");
	    if (neighbor == null || neighbor.HasPath) {
		    return null;
	    }
	    neighbor.distance = distance + 1;
	    neighbor.nextOnPath = this;
	    neighbor.ExitPoint = neighbor.transform.localPosition + direction.GetHalfVector();
	    neighbor.PathDirection = direction;
	    return neighbor.Content.BlocksPath ? null : neighbor;
    }
    
    public GameTile GrowPathNorth () => GrowPathTo(north, Direction.South);

    public GameTile GrowPathEast () => GrowPathTo(east, Direction.West);

    public GameTile GrowPathSouth () => GrowPathTo(south, Direction.North);

    public GameTile GrowPathWest () => GrowPathTo(west, Direction.East);
    
    public void ShowPath () {
	    if (distance == 0) {
		    arrow.gameObject.SetActive(false);
		    return;
	    }
	    arrow.gameObject.SetActive(true);
	    arrow.localRotation =
		    nextOnPath == north ? northRotation :
		    nextOnPath == east ? eastRotation :
		    nextOnPath == south ? southRotation :
		    westRotation;
    }
    
    public GameTileContent Content {
	    get => content;
	    set {
		    Debug.Assert(value != null, "分配给内容的 Null!");
		    if (content != null) {
			    content.Recycle();
		    }
		    content = value;
		    content.transform.localPosition = transform.localPosition;
	    }
    }
    
    public void HidePath () {
	    arrow.gameObject.SetActive(false);
    }
}